package com.sharemarking.application.common;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Controller基础类，实现基本的CRUD操作
 * @author song
 *
 * @param <E>
 * @param <R>
 */
public class BaseController<E extends BaseEntity,Dao extends BaseRepository<E>> {
	
	/*@ExceptionHandler
	public ResponseEntity<ExceptionDto> illegalStateException(IllegalStateException e){
		e.printStackTrace();
		ExceptionDto dto=new ExceptionDto("400001",e.getMessage());
		return new ResponseEntity<ExceptionDto>(dto,HttpStatus.BAD_REQUEST);
	}
	
	@ExceptionHandler
	public ResponseEntity<ExceptionDto> exception(Exception e){
		e.printStackTrace();
		ExceptionDto dto=new ExceptionDto("500001",e.getMessage());
		return new ResponseEntity<ExceptionDto>(dto,HttpStatus.INTERNAL_SERVER_ERROR);
	}
	
	@ExceptionHandler
	public ResponseEntity<ExceptionDto> exception(RuntimeException e){
		e.printStackTrace();
		ExceptionDto dto=new ExceptionDto("500002",e.getMessage());
		return new ResponseEntity<ExceptionDto>(dto,HttpStatus.INTERNAL_SERVER_ERROR);
	}*/
	
	@Autowired
	protected Dao dao;
	
	/**
	 * 列表与筛选接口，目前实现了字符串、整数、del_flag的筛选
	 * @param e
	 * @param page
	 * @param size
	 * @return
	 */
	@RequestMapping(value="index",method=RequestMethod.GET)
	public String index(E e,Integer page,Integer size,Model model){
		String[] s=this.getClass().getAnnotation(RequestMapping.class).value();
		if(page==null)page=0;
		else page-=1;
		if(size==null)size=30;
		PageRequest req=new PageRequest(page,size);
		Page<E> p=dao.findAll(new BaseSpecification<E>(e), req);
		model.addAttribute("page", p);
		model.addAttribute("search", e);
		return s[0]+"/index";
	}
	/**
	 * 获取实体接口
	 * @param e
	 * @return
	 */
	@RequestMapping(value="{id}",method=RequestMethod.GET)
	public String get(E obj,Model model){
		if(obj.getId()==0){
			model.addAttribute("obj", obj);
		}else model.addAttribute("obj", dao.findOne(obj.getId()));
		String[] s=this.getClass().getAnnotation(RequestMapping.class).value();
		return s[0]+"/form";
	}
	/**
	 * id==0  =>  新增实体
	 * id!=0  =>  更新实体
	 * @param e
	 * @return
	 */
	@RequestMapping(value="{id}",method=RequestMethod.POST)
	@Transactional
	public String post(E target,Model model){
		if(target.getId()==0){
			dao.save(target);
			return "redirect:index";
		}else {
			E e=dao.findOne(target.getId());
			if(e==null)return null;
			Field[] fields=target.getClass().getDeclaredFields();
			for(Field f:fields){
				if(Modifier.isPublic(f.getModifiers())||Modifier.isStatic(f.getModifiers()))continue;
				try {
					PropertyDescriptor pd = new PropertyDescriptor(f.getName(),target.getClass());
					Method getMethod=pd.getReadMethod();
					Object o=getMethod.invoke(target);
					if(o!=null && !(o instanceof BaseEntity)){
						Method setMethod=pd.getWriteMethod();
						setMethod.invoke(e, o);
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
			if(target.getRemarks()!=null)e.setRemarks(target.getRemarks());
			return "redirect:index";
		}
	}
	/**
	 * 逻辑删除
	 * @param id
	 */
	@RequestMapping(value="{id}/delete",method=RequestMethod.GET)
	@Transactional
	public String delete(@PathVariable("id")Integer id){
		dao.findOne(id).setDelFlag(true);
		return "redirect:../index";
	}
}
